package Pet.Management.service.impl;

import Pet.Management.domain.entity.PetCareOrder;
import Pet.Management.domain.entity.TaskNode;
import Pet.Management.repository.PetCareOrderRepository;
import Pet.Management.repository.TaskNodeRepository;
import Pet.Management.service.OrderAcceptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class OrderAcceptServiceImpl implements OrderAcceptService {

    @Autowired
    private PetCareOrderRepository orderRepository;

    @Autowired
    private TaskNodeRepository taskNodeRepository;

    @Override
    @Transactional
    public void acceptOrder(Long orderId, Long acceptorId, List<TaskNode> taskNodes) {
        PetCareOrder order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("Order not found"));

        if (!canAcceptOrder(orderId, acceptorId)) {
            throw new RuntimeException("Cannot accept this order");
        }

        // Update order status and acceptor
        order.setAcceptorId(acceptorId);
        order.setStatus(1); // 1 represents accepted status
        order.setUpdateTime(LocalDateTime.now());
        orderRepository.save(order);

        // Save task nodes
        if (taskNodes != null && !taskNodes.isEmpty()) {
            for (TaskNode node : taskNodes) {
                node.setOrderId(orderId);
                node.setCreateTime(LocalDateTime.now());
                node.setStatus(0); // 0 represents pending status
            }
            taskNodeRepository.saveAll(taskNodes);
        }
    }

    @Override
    public boolean canAcceptOrder(Long orderId, Long acceptorId) {
        PetCareOrder order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("Order not found"));

        // Check if order is available
        if (order.getStatus() != 0 || order.getAcceptorId() != null) {
            return false;
        }

        // Check if acceptor is not the publisher
        if (order.getPublisherId().equals(acceptorId)) {
            return false;
        }

        return true;
    }

    @Override
    public List<PetCareOrder> getAvailableOrders(Long userId) {
        return orderRepository.findAvailableOrders();
    }

    @Override
    public List<PetCareOrder> getAcceptedOrders(Long userId) {
        return orderRepository.findByAcceptorId(userId);
    }

    @Override
    @Transactional
    public void cancelAcceptance(Long orderId, Long acceptorId) {
        PetCareOrder order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("Order not found"));

        // Verify the order belongs to this acceptor
        if (!acceptorId.equals(order.getAcceptorId())) {
            throw new RuntimeException("Not authorized to cancel this order");
        }

        // Check if order status is valid for cancellation
        if (order.getStatus() != 1) { // 1 represents accepted status
            throw new RuntimeException("Order cannot be cancelled in current status");
        }

        // Delete task nodes
        taskNodeRepository.deleteByOrderId(orderId);

        // Reset order status
        order.setAcceptorId(null);
        order.setStatus(0); // 0 represents available status
        order.setUpdateTime(LocalDateTime.now());
        orderRepository.save(order);
    }
} 